Chapter 21: Completing a Todo

Let ’ s add a mark ‘ Complete ’ button for each Todo in todos-list.js by adding the below in bold:

Modify Bold Code

<Button variant="outline-info" className="me-2">

Edit

</Button>

</Link>

<Button variant="outline-danger" onClick={() => deleteTodo(todo.id)} className="me-2">

Delete

</Button>

<Button variant="outline-success" onClick={() => completeTodo(todo.id)}>

Complete

</Button>

Next, add in the codes for completeTodo just above return:

Modify Bold Code

const completeTodo = (todoId) => {

TodoDataService.completeTodo(todoId, props.token)

.then(response => {

retrieveTodos();

console.log("completeTodo", todoId);

})

.catch(e => {

console.log(e);

})

}

return (

<Container>

Code Explanation

Analyze Code

<Button variant="outline-success" onClick={() => completeTodo(todo.id)}>

In the complete button, we pass in the todo id into completeTodo.

In completeTodo, we then call completeTodo in TodoDataService which calls the complete API endpoint we

implemented earlier:

Analyze Code

completeTodo(id, token){

axios.defaults.headers.common["Authorization"] = "Token " + token;

return axios.put(`http://localhost:8000/api/todos/${id}/complete`);

}

Remember that the complete endpoint is supported by TodoToggleComplete view in todobackend/api/views.py:

Analyze Code

class TodoToggleComplete(generics.UpdateAPIView):

serializer_class = TodoToggleCompleteSerializer

permission_classes = [permissions.IsAuthenticated]

def get_queryset(self):

user = self.request.user

return Todo.objects.filter(user=user)

def perform_update(self,serializer):

serializer.instance.completed=not(serializer.instance.completed)

serializer.save()

Back in todos-list.js, we then add a callback function that is called when deleteTodo completes:

Analyze Code

const completeTodo = (todoId) => {

TodoDataService.completeTodo(todoId, props.token)

.then(response => {